from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import BasePermission

from django.core.mail import send_mail
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import User
from django.views import View
from redis import StrictRedis
import json
import re
#  导入系统提供的认证函数
from django.contrib.auth import authenticate  # 此方法接收request，username, password 认证通过返回用户，否则返回空

from users.serializer import UserSerializer
from rest_framework import viewsets

'''
# 'rest_framework.permissions.IsAdminUser',  # 管理员可以访问
# 'rest_framework.permissions.IsAuthenticated',  # 认证用户可以访问
# 'rest_framework.permissions.IsAuthenticatedOrReadOnly',  # 认证用户可以访问, 否则只能读取
# 'rest_framework.permissions.AllowAny',  # 所有用户都可以访问
'''
from users.users_utils import generate_verify_email_url, decode_email_token
from rest_framework.permissions import BasePermission, IsAdminUser, IsAuthenticated, IsAuthenticatedOrReadOnly, AllowAny


# 用户注册接口
class RegisterView(View):
    def post(self, request):
        data = json.loads(request.body.decode())
        username = data.get('username')
        password = data.get('password')
        password2 = data.get('password2')
        mobile = data.get('mobile')
        sms_code = data.get('sms_code')
        allow = data.get('allow')
        # 2.校验参数
        # 判断参数是否齐全
        if not all([username, password, password2]):
            return JsonResponse({'msg': '获取的数据缺少', 'code': 999})
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return JsonResponse({'msg': '请输入5-20位的账号', 'code': 999})
        # 判断密码是否是8-20个字符
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'msg': '请输入8-20位的密码', 'code': 999})
        # 判断手机号格式是否正确
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'msg': '手机号码格式不正确', 'code': 999})
        # 判断验证码是否存在
        if not sms_code:
            return JsonResponse({'msg': '没用验证码', 'code': 999})
        # 判断两次密码是否一致
        if password != password2:
            return JsonResponse({'msg': '两次输入的密码不一致', 'code': 999})
        # 判断手机验证码
        client = StrictRedis()
        redis_sms_code = client.get(mobile)
        if redis_sms_code:
            redis_sms_code = redis_sms_code.decode()
        else:
            redis_sms_code = None
        if sms_code == redis_sms_code:
            pass
        else:
            return JsonResponse({'msg': '短信验证码错误', 'code': '999'})
        # 判断是否勾选议用户协
        if not allow:
            return JsonResponse({'msg': '请勾选用户协议', 'code': '999'})

        # 3. 生成用户
        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except Exception as e:
            return JsonResponse({'msg': '注册失败', 'code': 999})
        return JsonResponse({'msg': 'OK', 'code': 0, 'username': user.username, 'id': user.id, 'token': 000})


# 用户登录接口
class LoginView(View):
    def post(self, request):
        data = json.loads(request.body.decode())
        username = data.get('username')
        password = data.get('password')

        if not all([username, password]):
            return JsonResponse({'msg': '获取的数据缺少', 'code': 999})
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return JsonResponse({'msg': '请输入5-20位的账号', 'code': 999})
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'msg': '请输入8-20位的密码', 'code': 999})
        # 认证用户,   status_code 200  登录成功
        user = authenticate(request, username=username, password=password)
        if user:  # 认证成功
            return JsonResponse({'code': '0', 'msg': '登陆成功',
                                 'username': user.username, 'id': user.id, 'token': '000'})

        # try:
        #     user = User.objects.get(username=username, password=password)
        # except Exception as e:
        #     return JsonResponse({'code': 999, 'msg': '登陆失败'})
        # if user.check_password(password):
        #     return JsonResponse({'code': 0, 'msg': '登陆成功', 'username': user.username, 'id': user.id, 'token': 000})
        else:
            return JsonResponse({'msg': '登录失败', 'code': 999})


# 判断用户名是否重复注册
class UsernameCountView(View):
    def get(self, request, username):
        """
        :param request: 请求对象
        :param username: 用户名
        :return: JSON
        """
        count = User.objects.filter(username=username).count()
        return JsonResponse({'msg': 'ok', 'code': '0', 'count': count})


# 判断手机号是否重复注册检测
class MobileCountView(View):
    def get(self, request, mobile):
        """
        :param request:
        :param mobile:
        :return:
        """
        count = User.objects.filter(mobile=mobile).count()
        return JsonResponse({'msg': 'ok', 'code': '0', 'count': count})


class PageNum(PageNumberPagination):
    page_size_query_param = 'page_size'


class MyPermission(BasePermission):
    # 必须继承BasePermission
    def has_permission(self, request, view):
        """判断用户对模型有没有访问权"""
        if request.user.is_superuser:
            # 管理员对用户模型有访问权
            return True
        elif view.kwargs.get('pk') == str(request.user.id):
            # 携带的id和用户的id相同时有访问权
            return True
        return False


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()  # 视图集默认定义了数据
    serializer_class = UserSerializer  # 优先使用 get_serializer_class 返回的序列化器


class EmailAddView(APIView):
    # 自定义权限类
    # permission_classes = (IsAdminUser,)

    # 1. 获取email验证码的接口
    def post(self, request):
        # 1. 获取数据
        email = request.data.get('email')
        # 2. 校验数据
        pass
        # 3. 保存数据
        user = request.user
        user.email = email
        user.email_active = False
        user.save()
        # 4. 发送认证邮件
        # 4.1 生成token, 作为邮件内容
        # http://127.0.0.1:8000/emails/verification/?token=eyJhbGciOiJIUzUxMiIsImlhdCI6MTYwNDg0MDQ1MywiZXhwIjoxNjA0ODQwNzUzfQ.eyJ1c2VyaWQiOjF9.9R2YUJy7DCsmBOn9IKoKgv5haU40WEbnW2j7nuPSt1_tbZYJvTXY6iS6-aJVNu1vom_XNSOsDmQV5xSJm49G-g
        verify_email_url = generate_verify_email_url(user.id)
        # 4.2 发送邮件
        send_mail(subject="美多商场激活邮件",
                  message='请点击以激活邮件:%s' % verify_email_url,
                  from_email='13546493199@163.com',
                  recipient_list=[user.email])
        pass
        # 5. 返回结果
        return Response({'code': 0, 'msg': '验证邮件发送成功'})


class EmailVerificationView(View):
    def get(self, request):
        token = request.GET.get('token')
        user_id = decode_email_token(token)
        if user_id:
            user = User.objects.get(id=user_id)
            user.email_active = True
            user.save()
            return HttpResponse('邮箱已激活')
        else:
            return HttpResponse('token失效')
